<!--
  注：目前存在的问题是将easy-input放入对话框中，且启用日期/时间选择器功能，会出错，如果直接用q-menu放在q-input中，而不是用easy-input
  多包装一层，那就不会出错，这个错误能重现，但有些难跟Quasar的作者反映，需要些时间。

  对q-input的封装，提供日期/时间选择的选项
  支持的属性有：
  * class                      - QInput的class
  * style                      - QInput的style
  * bg-color                   - QInput的bg-color
  * error                      - QInput的error
  * error-message              - QInput的error-message
  * readonly                   - QInput的readonly
  * autofocus                  - QInput的autofocus
  * modelValue(v-model)        - QInput的modelValue
  * placeholder                - QInput的placeholder
  * append-icon-show           - 显示QInput的append插槽中的图标，默认false
  * append-icon-name           - 显示在QInput的append插槽中的图标的名称
  * append-icon-color          - 显示在QInput的append插槽中的图标的颜色，默认grey-6
  * maxlength                  - QInput的max-length，默认30
  * clearable                  - QInput的clearable，默认true
  * use-date-picker            - 是否使用DatePicker，默认false
  * use-time-picker            - 是否使用TimePicker，默认false
  * default-date-for-picker    - 当使用DatePicker时，如果modelValue没值，那Picker就默认使用这个值显示
  * default-time-for-picker    - 当使用TimePicker时，如果modelValue没值，那Picker就默认使用这个值显示
  * select-all-on-focus        - 获得焦点时自动选中全部文本，默认false
  * hour-options               - 可以选择的时间段，默认为0-23点 此选项若不是默认值可能会影响一些功能的使用 比如选取当前时间(time)的时候时间不在可选范围
  * minute-options             - 可以选择的分钟时间段,默认五分钟间隔
  支持的事件有：
  * update:modelValue(v-model) - v-model的事件
  支持的方法有：
  * focus()                    - 让QInput获得焦点
-->
<template>
  <q-input ref='theInput' :bg-color="props.bgColor" :error-message="props.errorMessage" :error="props.error" :hide-bottom-space="true"
    :clearable="props.clearable" dense no-error-icon outlined square stack-label v-model="realValue"
    :readonly="props.readonly" :disable="props.disable" :maxlength="props.maxlength" :placeholder="props.placeholder"
    :autofocus="props.autofocus" @focus="onFocus">
    <template v-slot:append v-if="props.appendIconShow">
      <q-icon :name="iconName" :color="props.appendIconColor" />
    </template>
    <q-menu :fit="false" ref="dtp-container-menu" transition-hide="none" transition-show="none"
      v-if="props.useDatePicker || props.useTimePicker">
      <q-date :title="realValue" @update:model-value="() => $refs['dtp-container-menu'].hide()"
        mask="YYYY-MM-DD" :subtitle="$t('当前选中日期')" today-btn v-model="realValue"
        v-if="props.useDatePicker && !props.useTimePicker" />
      <time-picker v-model="realValue" :title="realValue" v-if="!props.useDatePicker && props.useTimePicker"
        :hour-options="hourOptions" :minute-options="minutesOptions"/>
      <div class="row items-start q-gutter-xs" v-if="props.useDatePicker && props.useTimePicker">
        <q-date :title="realValueDate" mask="YYYY-MM-DD" today-btn v-model="realValueDate" />
        <time-picker v-model="realValueTime" :title="realValueTime" :hour-options="hourOptions" :minute-options="minutesOptions"/>
      </div>
    </q-menu>
  </q-input>
</template>

<script lang="ts">
export default {
  name: 'EasyInput',
}
</script>

<script lang="ts" setup>

import {computed, ref} from 'vue'
import dayjs from 'dayjs'
import {QInput} from 'quasar'
import _ from 'lodash'

interface PropsDef {
  // 背景色
  bgColor?: string,
  // 验证是否有错误
  error?: boolean
  // 验证错误的消息
  errorMessage?: string
  // 是否只读状态
  readonly?: boolean
  // 是否禁用状态
  disable?: boolean
  // 是否自动获得焦点
  autofocus?: boolean
  // 传递的v-model的绑定值
  modelValue: any
  // 占位文本显示
  placeholder?: string
  // 是否显示append插槽上的图标
  appendIconShow?: boolean
  // 显示在append插槽上的图标的名称（如果使用了DatePicker，此值默认为'event'）
  appendIconName?: string
  // 显示在append插槽上的图标的颜色
  appendIconColor?: string
  // 允许的文本的最大长度
  maxlength?: number
  // 是否清除
  clearable?: boolean
  // 是否使用DatePicker
  useDatePicker?: boolean
  // 是否使用TimePicker
  useTimePicker?: boolean
  // 当使用DatePicker时，如果modelValue没值，那Picker就默认使用这个值显示，格式为 YYYY-MM-DD
  defaultDateForPicker?: string
  // 当使用TimePicker时，如果modelValue没值，那Picker就默认使用这个值显示，格式为 HH:mm
  defaultTimeForPicker?: string
  // 获得焦点时自动选中全部文本，默认false
  selectAllOnFocus?: boolean
  hourOptions?: string[]
  minutesOptions?: string[]
}

const props = withDefaults(defineProps<PropsDef>(), {
  bgColor: '',
  error: false,
  errorMessage: '',
  readonly: false,
  disable: false,
  autofocus: false,
  placeholder: '',
  appendIconShow: false,
  appendIconName: '',
  appendIconColor: 'grey-6',
  maxlength: 30,
  clearable: true,
  useDatePicker: false,
  useTimePicker: false,
  defaultDateForPicker: '',
  defaultTimeForPicker: '',
  selectAllOnFocus: false,
  hourOptions: () => ['00','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23'],
  minutesOptions: () => ['00','05','10','15','20','25','30','35','40','45','50','55'],
})

const iconName = computed(() => {
  if (props.appendIconName) {
    return props.appendIconName
  }
  if (props.useDatePicker && props.useTimePicker) {
    return 'eva-calendar'
  }
  if (props.useDatePicker) {
    return 'event'
  }
  if (props.useTimePicker) {
    return 'access_time'
  }
  return ''
})

const emit = defineEmits<{
  (e: 'update:modelValue', data: any): void
}>()

// 真值
const realValue = computed({
  get() {

    return props.modelValue
  },
  set(val: any) {
    emit('update:modelValue', val)
  },
})

const currValForPickers = computed(() => {
  if (props.modelValue) {
    return props.modelValue as string
  }
  return (props.defaultDateForPicker ? props.defaultDateForPicker : dayjs().format('YYYY-MM-DD'))
    + ' '
    + (props.defaultTimeForPicker ? props.defaultTimeForPicker : (_.indexOf(props.hourOptions,dayjs().format('HH'))!==-1?
      `${dayjs().format('HH')}:${Math.round(Number(dayjs().format('mm'))/5)*5===60?'00':Math.round(Number(dayjs().format('mm'))/5)*5}`:''))
})

// 真值（DatePicker和TimePicker同时要显示时使用）
const realValueDate = computed({
  get() {
    if (!props.modelValue) {
      return props.defaultDateForPicker
    }
    let day = dayjs(props.modelValue)
    if (day.isValid()) {
      return day.format('YYYY-MM-DD')
    } else {
      return ''
    }
  },
  set(val: any) {
    if (!val) {
      //日期清空了，时间也不复存在
      emit('update:modelValue', '')
      if (props.defaultDateForPicker){
        val = props.defaultDateForPicker
      }
    }
    let dayCurr = dayjs(currValForPickers.value)
    if (!dayCurr.isValid()) {
      dayCurr = dayjs()
      dayCurr = dayjs(dayCurr.format('YYYY-MM-DD')) //只保留日期，时间部分为0:0:0.0
    }
    let dayToSet = dayjs(val)
    if (dayToSet.isValid()) {
      emit('update:modelValue', dayToSet.format('YYYY-MM-DD') + ' ' + dayCurr.format('HH:mm'))
    }
  },
})

// 真值（DatePicker和TimePicker同时要显示时使用）
const realValueTime = computed({
  get() {
    if (!props.modelValue) {
      return props.defaultTimeForPicker
    }
    let day = dayjs(props.modelValue)
    if (day.isValid()) {
      return day.format('HH:mm')
    } else {
      return ''
    }
  },
  set(val: any) {
    let dayCurr = dayjs(currValForPickers.value)
    if (!dayCurr.isValid()) {
      dayCurr = dayjs()
    }
    let dayToSet = dayjs(dayCurr.format('YYYY-MM-DD') + ' ' + (val as string))
    if (dayToSet.isValid()) {
      emit('update:modelValue', dayToSet.format('YYYY-MM-DD HH:mm'))
    }
  },
})

const onFocus = function (el: Event) {
  if (props.selectAllOnFocus) {
    $f.ui.select(el)
  }
}

const theInput = ref<QInput | null>(null)

const focus = () => {
  theInput.value?.focus()
}

defineExpose({
  focus
})

</script>
